﻿/*
 * modbusrtumaster.hpp
 *
 *  Created on: 2017年3月1日
 *      Author: work
 */

#ifndef _DM_OS_PROTOCOL_MODBUSRTUMASTER_HPP_
#define _DM_OS_PROTOCOL_MODBUSRTUMASTER_HPP_

#include <dm/export.hpp>

#ifndef DM_API_OS_PROTOCOL
#define DM_API_OS_PROTOCOL DM_API_IMPORT
#endif

#include <dm/protocol/modbusrtumaster.hpp>
#include <dm/os/protocol/protocolmasters.hpp>

namespace dm{
namespace os{
namespace protocol{

/**
 * Modbus RTU主站。本类设计用于处理多个子站
 */
class DM_API_OS_PROTOCOL CModbusRtuMaster:virtual public dm::protocol::CModbusRtuMaster,virtual public CProtocolMasters{
public:
	typedef dm::protocol::CFrameModbusRtu frame_modbus_t;

	CModbusRtuMaster();
	virtual ~CModbusRtuMaster();

	/**
	 * 设置子设备数
	 * @param num
	 */
	void setSubDevNum( int num );

	/**
	 * 获取子设备数
	 * @return
	 */
	inline const int& getSubDevNum()const{
		return getDevcieCount();
	}

	/**
	 * 切换当前设备
	 * @param idx
	 */
	void setCurDev( int idx );

	/**
	 * 设置modbus地址
	 * @param idx
	 * @param addr
	 */
	void setSubAddress( int idx,address_t addr );

	/**
	 * 获取modbus地址
	 * @param idx
	 * @return
	 */
	address_t getSubAddress( int idx )const;

	/**
	 * 获取当前设备的地址
	 * 这个函数正常时应该于getModbusAddress()的结果相同
	 * @return
	 */
	inline dm::uint16 curAddress()const{
		return getSubAddress(getCurDev());
	}

	inline const int& getNextDevIndex()const{
		return m_nextDevIndex;
	}

	inline void resetNextDevIndex(){
		m_nextDevIndex = 0;
	}

	/**
	 * 移动下一个设备索引，并检测是否全部循环了一遍
	 * @return 是否重新计数
	 */
	bool moveNextOver();

protected:
	EAction taskEnd_remoteControl( const ts_t& ts,const rts_t& rts );
	EAction taskEnd_parameters( const ts_t& ts,const rts_t& rts );
	EAction taskEnd_call( const ts_t& ts,const rts_t& rts );

private:
	address_t* m_modbusAddrs;	// 子站地址

	int m_nextDevIndex;	// 下一个需要召唤的设备
};

}
}
}



#endif /* INCLUDE_DM_OS_PROTOCOL_MODBUSRTUMASTER_HPP_ */
